import * as c from '@/services/consts';
import * as api from '@/services/checkTask';
import {
  ArrowDownOutlined,
  ArrowUpOutlined,
  CheckCircleFilled,
  CloseCircleFilled,
  EditOutlined,
} from '@ant-design/icons';
import { DrawerForm, ProFormInstance } from '@ant-design/pro-form';
import type { ActionType, ProColumns } from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table';
import {
  Badge,
  Button,
  Checkbox,
  Col,
  Descriptions,
  List,
  message,
  Popconfirm,
  Radio,
  Row,
  Segmented,
  Space,
  Tag,
  Tooltip,
} from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import { useModel } from 'umi';
import dayjs from 'dayjs';
import * as utils from '@/utils/utils';
import NodeForm from '../VpnServer/components/VpnServerForm';
import BatchChangeForm from '../VpnServer/components/BatchChangeForm';
import IdcManualForm from '../IdcApiEvent/ManualForm';
import BroadcastForm from '../BroadcastIp/ChangeForm';
// import RecheckServerForm from './RecheckForm';
import RecheckDomainForm from './RecheckDomainForm';
import RecheckManualForm from './RecheckManualForm';

type VpnServerFormProps = {
  visible: boolean;
  ver: string | undefined;
  groupId: string | undefined;
  onCancel: () => void;
  onCancelAndReload: () => void;
};

const VpnServerForm: React.FC<VpnServerFormProps> = (props) => {
  const { visible, onCancel, onCancelAndReload, ver, groupId } = props;

  if (!visible) {
    return null;
  }

  const actionRef = useRef<ActionType>();
  const formRef = useRef<ProFormInstance>();
  const actionServerRef = useRef<ActionType>();
  const { hasRight } = useModel('useAuthModel');
  const [myloading, setMyloading] = useState<boolean>(true);
  const [dataSource, setDataSource] = useState<API.CheckTaskReportItem | undefined>(undefined);
  const [selectIds, setSelectIds] = useState<any[]>([]);
  const [selectInstances, setSelectInstances] = useState<any[]>([]);
  const [selectInstanceIds, setSelectInstanceIds] = useState<any[]>([]);
  const [selectIpIds, setSelectIpIds] = useState<any[]>([]);
  const [formBatchChangeVisible, setFormBatchChangeVisible] = useState<boolean>(false);
  const [formNodeVisible, setFormNodeVisible] = useState<boolean>(false);
  // const [displayOnlyError, setDisplayOnlyError] = useState<boolean>(false);
  const [displayOnlyErrorNode, setDisplayOnlyErrorNode] = useState<boolean>(false);
  const [displayOnlyErrorCheckGroup, setDisplayOnlyErrorCheckGroup] = useState<boolean>(false);
  const [displayStatus, setDisplayStatus] = useState<number | undefined>(1);
  const [formIdcManualVisible, setFormIdcManualVisible] =useState<boolean>(false);
  const [formBroadcastVisible, setFormBroadcastVisible] =useState<boolean>(false);
  // const [formRecheckServerVisible, setFormRecheckServerVisible] =useState<boolean>(false);
  const [formRecheckDomainVisible, setFormRecheckDomainVisible] =useState<boolean>(false);
  const [formRecheckCustomVisible, setFormRecheckCustomVisible] =useState<boolean>(false);

  // const [currentNode, setCurrentNode] = useState<API.VpnServer | undefined>(
  //   undefined,
  // );
  const [currentNodeId, setCurrentNodeId] = useState<string | undefined>(
    undefined,
  );

  let tableGroupTitle: string = '';
  let tableGroupFont: string = 'normal';

  

  const loadData = async () => {
    setMyloading(true);
    const result = await api.report({ ver, groupId, onlyErrorNode: displayOnlyErrorNode, onlyErrorCheckGroup: displayOnlyErrorCheckGroup, displayStatus: displayStatus });
    if (result && result.success) {
      setDataSource(result.data);
    }
    setMyloading(false);
  };

  useEffect(() => {
    loadData();
  }, [displayOnlyErrorNode, displayStatus, displayOnlyErrorCheckGroup]);

  
  
  const handleRecheckSubmit = async (ver: string | undefined, instIds:number[] | undefined) => {
    const result = await api.create({recheckId: ver, instIds: instIds, ipIds: selectIpIds});
    if (result && result.success) {
      onCancelAndReload();
    }
  };


  const getSelectCustoms = () => {
    if(selectInstances){
      let options = [];
      for(var inst of selectInstances){
        if(inst?.data){
          for(var d of inst.data){
            options.push(d.ip);
          }
        }
      }
      return options;
    }
    return undefined;
  }

  const handleRemove = async (ver: string | undefined) => {
    if (!ver) {
      message.error('无效版本号');
      return;
    }
    const result = await api.remove({ ver: ver });
    if (result.success) {
      onCancelAndReload();
    }
  };

  const clientColumns: ProColumns<API.CheckProgress>[] = [
    {
      title: '状态',
      align: 'center',
      width: 60,
      dataIndex: 'status',
      sorter: true,
      search: false,
      render: (_, record) => {
        return record.server?.status == true ? (
          <Badge count={<CheckCircleFilled style={{ color: '#52c41a' }} />} />
        ) : (
          <Badge count={<CloseCircleFilled style={{ color: '#f50' }} />} />
        );
      },
    },
    {
      title: '在线',
      align: 'center',
      width: 60,
      dataIndex: 'online',
      sorter: true,
      search: false,
      render: (_, record) => {
        return record.server?.online == true ? (
          <Badge count={<CheckCircleFilled style={{ color: '#52c41a' }} />} />
        ) : (
          <Badge count={<CloseCircleFilled style={{ color: '#f50' }} />} />
        );
      },
    },
    {
      title: '检测端',
      width:200,
      dataIndex: 'serverId',
      render: (_, record) => {
        return record.server?.id;
      },
    },
    {
      title: '检测端IP',
      dataIndex: 'ip',
      width:250,
      render: (_, record) => {
        return <>{record.serverIp} {record.network ? <Tag color='blue'>{record.network}</Tag> : ''}</>;
      },
    },
    {
      title: '进度',
      dataIndex: 'percent',
      width:80,
      render: (_, record) => {
        if (record.percent == 100) {
          return '完成';
        } else {
          return record.percent >=0 ? `${record.percent} %` : '--';
        }
      },
    },
    {
      title: '开始时间',
      dataIndex: 'startTime',
    },
    {
      title: '结束时间',
      dataIndex: 'endTime',
    },
  ];

  const columns: ProColumns<API.CheckReport>[] = [
    {
      title: 'ID',
      dataIndex: 'instanceId',
      width: 10,
      hideInTable:true
    },
    {
      title: '分组',
      dataIndex: 'groupNames',
      width: 300,
      hideInTable:!(dataSource?.task?.job == c.CheckJob.HttpPost.value && (dataSource?.task?.instanceIds?.length > 0 || dataSource?.task?.groupIds?.length > 0 || dataSource?.task?.supplierIds?.length > 0)),
      render: (_, record) => {
        let text = record.groupNames?.map((val)=>val).join(',');
        if (tableGroupTitle != text) {
          tableGroupFont = tableGroupFont == 'blue' ? 'green' : 'blue';
        }
        tableGroupTitle = text;
        return (<div>
          <div>
            <Tag color={record.serverStatus == true ? 'blue' : 'error'}>{record.instanceId}</Tag>
            {record.changeIpLastTime ? <Tag color={
                                record.changeIpLastStatus == 2
                                  ? 'success'
                                  : 'error'
                              }>更换 {utils.formatDate(record.changeIpLastTime)}</Tag> :
            record.startTime ? <Tag>运行 {utils.formatDate(record.startTime)}</Tag> : ''
            }
          </div>
          <div style={{ color: tableGroupFont }}>{text}</div>
          <div style={{ color: tableGroupFont }}>{record.serverName}</div>
        </div>);
      },
    },
    {
      title: '检测结果',
      dataIndex: 'groupNames',
      render: (_, record) => {
        if (!record.data) {
          return <></>;
        }
        return record.data.map((item) => {
          return (
            <List
              itemLayout="horizontal"
              dataSource={[item]}
              renderItem={(itemIp, index) => (
                <List.Item>
                  <List.Item.Meta style={{marginTop:-18}}
                    description={<>
                    <Descriptions layout="vertical" column={item.reports.length>12?12:item.reports.length}>
                      <Descriptions.Item labelStyle={{marginBottom:-15}} contentStyle={{marginBottom:-20}} label={
                        <Space style={{color:'#777', fontWeight:'bold'}}>
                        <div style={{ color: tableGroupFont }}>{item.ip}</div>
                        {hasRight('vpnserver_update') && (dataSource?.task?.job == c.CheckJob.HttpPost.value && (dataSource?.task?.instanceIds?.length > 0 || dataSource?.task?.groupIds?.length > 0)) ? (
                          <><a onClick={(e) => {
                              if(record.serverId){
                                setFormNodeVisible(true);
                                // setCurrentNode(record.server);
                                setCurrentNodeId(record.serverId);
                              }
                            }}
                          >{' '}<EditOutlined />
                          </a>
                          {item.ipCountry ?
                          <span style={{color:'#999', fontWeight:'normal'}}><Tag color='blue'>{item.geoipIsp}</Tag>{item.ipCountry} / {item.ipProvince} / {item.ipNetwork}</span>
                          : ''}
                          </>
                        ) : ''}</Space>
                      }>
                        <Row gutter={item.reports.length>12?12:item.reports.length}>
                        {item.reports?.map((rep) => {
                          // if(displayOnlyError == true && rep.ping == true) return <></>;
                          return (
                            <Col style={{marginRight:10}}>
                            <Tooltip title={<div>
                                  {rep.delay == 0 ? <div style={{color:'red', backgroundColor:'#fff'}}>延时：0ms</div> : rep.delay > 0 ? <div style={{color:'#999', backgroundColor:'#fff'}}>延时：{rep.delay}ms</div> :''} 
                                  <div style={{maxWidth:900, maxHeight:600, overflow:'auto'}}>{rep.logData?.map((c)=><div>{c}</div>)}</div>
                                </div>} overlayStyle={{minWidth:600, maxWidth: 900}}>
                                <Tag color={rep.ping == true ? 'success' : 'error'} style={{marginRight:-3,width:100, overflowX:'hidden', overflowY:'hidden'}}>
                                  <b>{rep.serverId}</b>{rep.delay == 0 ? <span style={{color:'red'}}>&nbsp;0ms</span> : rep.delay > 0 ? <span style={{color:'#999'}}>&nbsp;{rep.delay}ms</span> :''}
                                </Tag></Tooltip>

                              {dataSource?.task?.job == "speedtest" ? 
                                <Tooltip title={<div style={{maxWidth:300, maxHeight:600, overflow:'auto'}}>
                                    <div>测速服务器国家：{rep.serverCountry}</div>
                                    {/* <div>测速服务器距离：{rep.serverDistance}</div>
                                    <div>测速服务器延迟：{rep.serverLatency}</div> */}
                                    <div>测速服务器出口IP：{rep.exportIp}</div>
                                  </div>} 
                                  overlayStyle={{minWidth:300, maxWidth: 900}}>
                                    <Tag style={{marginRight:4}}>
                                      <ArrowDownOutlined />
                                      {utils.formatRateBit(rep.download)}
                                      &nbsp;
                                      <ArrowUpOutlined />
                                      {utils.formatRateBit(rep.upload)}
                                    </Tag>
                                </Tooltip>
                              : ''}

                              {dataSource?.task?.job == c.CheckJob.Ping.value ? 
                                <div style={{maxWidth:900, maxHeight:600, overflow:'auto', backgroundColor:'#fafafa'}}>{rep.logData?.map((c)=><div>{c}</div>)}</div>
                              : ''}

                            </Col>);
                          })}  
                        </Row>                          
                        </Descriptions.Item>
                    </Descriptions>
                    

                    </>}
                  />
                </List.Item>
              )}
            />
          );
        });
      },
    },
    {
      title: '服务器备注',
      dataIndex: 'serverRemark',
      width: 100,
      // ellipsis:true,
      hideInTable:!(dataSource?.task?.job == c.CheckJob.HttpPost.value && (dataSource?.task?.instanceIds?.length > 0 || dataSource?.task?.groupIds?.length > 0 || dataSource?.task?.supplierIds?.length > 0)),
    },
  ];

  return (
    <DrawerForm<API.CheckTask>
      open={visible}
      title={
        <>
          检测结果 <Tag color="blue">版本：{dataSource?.task?.id}</Tag>{' '}
          <Tag color="blue">下发：{dayjs(dataSource?.task?.createTime).format('YYYY-MM-DD HH:mm:ss')}</Tag>{' '}
          <Tag color="blue">更新：{dayjs(dataSource?.task?.updateTime).format('YYYY-MM-DD HH:mm:ss')}</Tag>{' '}
          <Tag color="blue">创建人：{dataSource?.task?.createUser}</Tag>
        </>
      }
      formRef={formRef}
      autoFocusFirstInput
      width={1200}
      // onFinish={handleFormSubmit}
      drawerProps={{
        // forceRender: true,
        // destroyOnClose: true,
        // closable: false,
        onClose: onCancel,
        maskClosable: false,
      }}
      submitter={{
        render: (props, defaultDoms) => {
          return [defaultDoms[0]];
        },
      }}
      loading={myloading}
    >
      <ProTable<API.VpnServerCheckProgress>
        rowKey="client"
        actionRef={actionRef}
        loading={myloading}
        options={{
          fullScreen: false,
          reload: false,
          setting: false,
          density: false,
        }}
        search={false}
        pagination={false}
        columns={clientColumns}
        expandable={undefined}
        dataSource={dataSource?.task?.progresss}
      />

      <ProTable<API.CheckReport>
        rowKey="serverId"
        actionRef={actionServerRef}
        headerTitle={<div style={{width:850}}>
          <div>
          <b>
            {dataSource?.task?.createTime ? dayjs(new Date()).format('YYYY-MM-DD') !=
              dayjs(dataSource?.task?.createTime).format('YYYY-MM-DD') ? <Tag color="#f50">非当天检测</Tag> : '' : ''
            }

            <Tag color={utils.getTextRanColor(dataSource?.task?.job ?? '')}>
              {c.getObjectText(c.CheckJobAllOptions, dataSource?.task?.job)}
            </Tag>

            <>{dataSource?.task?.mode ? 
            <Tag color={utils.getTextRanColor(dataSource?.task?.mode ?? '')}>{c.getObjectText(c.CheckModeOptions, dataSource?.task?.mode)}</Tag> 
            : ''}</>

            <Tag color={dataSource?.task?.level == c.CheckLevel.Urgent.value ? '#f50' : '#2db7f5'}>
              {c.getObjectText(c.CheckLevelOptions, dataSource?.task?.level)}
            </Tag>
            
            {dataSource?.task?.checkBlock == true ? (
              <Tag color="#2db7f5">检测被墙</Tag>
            ) : (
              ''
            )}
            {dataSource?.task?.checkStatus == 1 ? <Tag color="orange">{c.CheckTaskItemStatus.All.label}</Tag>
              : dataSource?.task?.checkStatus == 2 ? <Tag color="#f50">{c.CheckTaskItemStatus.Disable.label}</Tag>
             : ''}

             
            {/* <Tag color='#f50'>数量：{dataSource?.reports?.length}</Tag> */}
          </b>
          {/* <Checkbox onChange={(e) => { setDisplayOnlyError(e.target.checked);}} checked={displayOnlyError}>仅出错结果</Checkbox> */}
          {/* <Checkbox onChange={(e) => { setDisplayOnlyErrorNode(e.target.checked);}} checked={displayOnlyErrorNode}>仅出错项</Checkbox> */}
          
          <Space>
            <Radio.Group defaultValue="a">
              <Radio
                value="a"
                onClick={() => {
                  setDisplayOnlyErrorNode(undefined);
                  setDisplayOnlyErrorCheckGroup(undefined);
                }}
              >
                全部
              </Radio>
              <Radio
                value="b"
                onClick={() => {
                  setDisplayOnlyErrorNode(true);
                  setDisplayOnlyErrorCheckGroup(undefined);
                }}
              >
                仅出错项
              </Radio>
              <Radio
                value="c"
                onClick={() => {
                  setDisplayOnlyErrorNode(undefined);
                  setDisplayOnlyErrorCheckGroup(true);
                }}
              >
                仅出错组
              </Radio>
            </Radio.Group>
          </Space>
          
          <Segmented options={[ {label:'全部', value:1},c.CheckTaskItemStatus.Normal, c.CheckTaskItemStatus.Disable]} value={displayStatus} onChange={(val)=>{setDisplayStatus(Number(val))}} />
          
          </div>
          <div>
          <Tag color='blue'>服务器: {dataSource?.reports?.length}</Tag>
          <Tag color='blue'>IP: {dataSource?.ipCount}</Tag>
          <Tag color='error'><b>IP被墙: {dataSource?.blockCount}</b></Tag>
          {dataSource?.task?.name ? <span style={{color:'#D48806',marginTop:20}}><b>检测：{dataSource?.task?.name}</b></span> : ''}
          </div>
        </div>}
        loading={myloading}
        options={{
          fullScreen: false,
          reload: false,
          setting: false,
          density: false,
        }}
        search={false}
        pagination={false}
        columns={columns}
        expandable={undefined}
        dataSource={dataSource?.reports}
        toolbar={{
          filter: (
            <>
              <Space
                style={{
                  marginRight: '0px',
                  width:200
                }}
              >
              <span>
                  <Button onClick={async()=>{
                    await loadData();
                  }}>刷新</Button>
              </span>
                <span>
                  <Popconfirm
                    key="delete"
                    title="确定要删除吗?"
                    onConfirm={async () => {
                      await handleRemove(dataSource?.task?.id);
                    }}
                  >
                    <Button type="primary">删除</Button>
                  </Popconfirm>
                </span>
                <span>
                  <a
                    target="_blank"
                    key="excel"
                    href={`/admin-api/checktask/export?ver=${
                      ver ? ver : dataSource?.task?.id
                    }${selectIds?.map((val) => {return "&ids=" + val})
                    }&onlyErrorNode=${displayOnlyErrorNode}&onlyErrorCheckGroup=${displayOnlyErrorCheckGroup}&displayStatus=${displayStatus}`}
                  >
                    <ArrowDownOutlined />
                    下载
                  </a>
                </span>
              </Space>
            </>
          ),
        }}
        rowSelection={
          // !(dataSource?.task?.job == c.CheckJob.HttpPost.value && (dataSource?.task?.instanceIds?.length > 0 || dataSource?.task?.groupIds?.length > 0 || dataSource?.task?.supplierIds?.length > 0)) ? false : 
          {
          defaultSelectedRowKeys: [],
          onChange: (selectedRowKeys, selectedRows) => {
            console.log(selectedRowKeys,selectedRows);
            setSelectIds(selectedRowKeys);
            setSelectInstances(selectedRows);
            setSelectInstanceIds(selectedRows.map((val)=>val.instanceId));
            let ipIds = [];
            for(let row of selectedRows){
              if(!row.data) continue;
              for(let r of row.data){
                if(r.id) ipIds.push(r.id);
              }
            }
            setSelectIpIds(ipIds);
          },
        }}
        tableAlertRender={({
          selectedRowKeys,
          selectedRows,
          onCleanSelected,
        }) => (
          <Space size={24}>
            <span>
              已选 {selectedRowKeys.length} 条记录
              <a style={{ marginLeft: 8 }} onClick={onCleanSelected}>
                取消
              </a>
            </span>
            

            <span>
              {hasRight('vpnserver_update') ? (
                <a
                  onClick={async () => {
                    setFormBatchChangeVisible(true);
                  }}
                >
                  修改服务器信息
                </a>
              ) : (
                ''
              )}
            </span>

            <span>
              {hasRight('idcapievent_update') ? (
                <a
                  onClick={async () => {
                    setFormIdcManualVisible(true);
                  }}
                >
                  操作服务器
                </a>
              ) : (
                ''
              )}
            </span>

            
              {hasRight('broadcastip_update') && displayOnlyErrorNode ? (
            <span>
                <a
                  onClick={async () => {
                    setFormBroadcastVisible(true);
                  }}
                >
                  更换广播IP
                </a>
            </span>
              ) : (
                ''
              )}
            
            <span>
              {hasRight('checktask_create') ? (
                (dataSource?.task.job == c.CheckJob.CheckApi.value || dataSource?.task.customs?.length > 0 ) ?
                <a
                key="check_recheck1"
                onClick={() => {
                  if(dataSource?.task.job == c.CheckJob.CheckApi.value){
                    setFormRecheckDomainVisible(true);
                  }
                  else if(dataSource?.task.customs?.length > 0){
                    setFormRecheckCustomVisible(true);
                  }
                }}
              >
                重新检测
              </a> :
                <Popconfirm
                  key="check_recheck2"
                  title="确定要重新检测选中项吗?"
                  onConfirm={async () => {
                    await handleRecheckSubmit(dataSource?.task?.id, selectInstanceIds);
                  }}
                >
                  <a>重新检测</a>
                </Popconfirm>
              ) : (
                ''
              )}
            </span>

            <span>
              <a
                target="_blank"
                key="export_excel_select"
                href={`/admin-api/checktask/export?ver=${
                  ver ? ver : dataSource?.task?.id
                }${selectIds?.map((val) => {return "&ids=" + val})
                }&onlyErrorNode=${displayOnlyErrorNode}&onlyErrorCheckGroup=${displayOnlyErrorCheckGroup}&displayStatus=${displayStatus}`}
              >
                <ArrowDownOutlined />导出Excel
              </a>
            </span>
          </Space>
        )}
      />

      <NodeForm
        visible={formNodeVisible}
        loadNodeId={currentNodeId}
        // loadNodeId={currentNode?.id}
        // current={currentNode}
        checks={undefined}
        // defaultGroupIds={groupIds && groupIds.length > 0 ? groupIds : undefined}
        defaultGroupIds={undefined}
        // onSubmit={handleNodeFormSubmit}
        onSubmit={async() =>{
          // setCurrentNode(undefined);
          setCurrentNodeId(undefined);
          setFormNodeVisible(false);
          await loadData();
          // actionServerRef.current?.reload();
        }}
        onCancel={() => {
          setFormNodeVisible(false);
          // setCurrentNode(undefined);
          setCurrentNodeId(undefined);
        }}
      />
      
      
      <BatchChangeForm
        visible={formBatchChangeVisible}
        // onSubmit={handleFormBatchRemarkSubmit}
        selectIds={selectIds}
        onSubmit={async() => {          
          setFormBatchChangeVisible(false);
          await loadData();
          actionServerRef.current?.clearSelected?.();
          // actionServerRef.current?.reload();
        }}
        onCancel={() => {
          setFormBatchChangeVisible(false);
        }}
      />
      
      <IdcManualForm
        visible={formIdcManualVisible}
        instIds={selectInstanceIds}
        groupIds={undefined}
        serverIds={undefined}
        name={dataSource?.task?.name}
        onCancel={() => {
          setFormIdcManualVisible(false);
        }}
        onSubmit={() => {
          setFormIdcManualVisible(false);
          actionServerRef.current?.clearSelected?.();
          // actionRef?.current?.reload();
        }}
      />
      
      <BroadcastForm
        visible={formBroadcastVisible}
        servers={selectInstances}
        onCancel={() => {
          setFormBroadcastVisible(false);
        }}
        onSubmit={() => {
          setFormBroadcastVisible(false);
          actionServerRef.current?.clearSelected?.();
        }}
      />
      
      {/* <RecheckServerForm
        visible={formRecheckServerVisible}
        currentTask={dataSource?.task}
        onCancel={() => {
          setFormRecheckServerVisible(false);
        }}
        onSubmit={() => {
          setFormRecheckServerVisible(false);
          actionServerRef.current?.clearSelected?.();
        }}
      /> */}
      <RecheckDomainForm
        visible={formRecheckDomainVisible}
        currentTask={dataSource?.task}
        customs={getSelectCustoms()}
        onCancel={() => {
          setFormRecheckDomainVisible(false);
        }}
        onSubmit={() => {
          setFormRecheckDomainVisible(false);
          actionServerRef.current?.clearSelected?.();
        }}
      />
      <RecheckManualForm
        visible={formRecheckCustomVisible}
        currentTask={dataSource?.task}
        onCancel={() => {
          setFormRecheckCustomVisible(false);
        }}
        onSubmit={() => {
          setFormRecheckCustomVisible(false);
          actionServerRef.current?.clearSelected?.();
        }}
      />

    </DrawerForm>
  );
};

export default VpnServerForm;
